﻿using System;
using System.ComponentModel;
using System.Diagnostics;

namespace DotNetCRM.Core.ExtensionMethods
{
    public static class StringExtensions
    {
//        private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// Trims a string. If the string is null or empty after being trimmed 
        /// the method return null.
        /// </summary>
        /// <param name="s">the string to trim</param>
        /// <returns>the trimmed string or null</returns>
        public static string TrimOrNull(this string s)
        {
            if (s != null)
            {
                s = s.Trim();
                if (s.Length == 0)
                {
                    s = null;
                }
            }
            return s;
        }

        /// <summary>
        /// Trims a string. If the string is null 
        /// the method return Empty string.
        /// </summary>
        /// <param name="s">the string to trim</param>
        /// <returns>the trimmed string or empty string</returns>
        public static string TrimOrEmpty(this string s)
        {
            s = s != null 
                    ? s.Trim() 
                    : string.Empty;
            return s;
        }

        /// <summary>
        /// Returns true if the string is null or emtpy and optionally
        /// trims the string before testing
        /// </summary>
        /// <param name="s">the string to test</param>
        /// <returns>true if the string is null or emtpy</returns>
        public static bool IsNullOrEmptyTrimmed(this string s)
        {
            return String.IsNullOrEmpty((s != null) ? s.Trim() : s);
        }

        /// <summary>
        /// Checks parameter for null and throws <code>ArgumentNullException</code> if null.
        /// </summary>
        /// <param name="parm">the parameter to check for null</param>
        /// <exception cref="ArgumentNullException">parm is null</exception>
        public static void CheckNullOrEmpty(this string parm)
        {
            parm.CheckNull(null);
        }

        /// <summary>
        /// Checks parameter for null and throws <code>ArgumentNullException</code> if null.
        /// </summary>
        /// <param name="parm">the parameter to check for null</param>
        /// <param name="parmName">the _name of the parameter</param>
        /// <exception cref="ArgumentNullException">parm is null</exception>
        public static void CheckNullOrEmpty(this string parm, string parmName)
        {
            if (parm == null)
            {
                throw new ArgumentNullException(parmName);
            }
            if (parm.IsNullOrEmptyTrimmed())
            {
                throw new ArgumentException("Value cannot be empty.", parmName);
            }
        }


        /// <summary>
        /// Converts the specified text to an object 
        /// </summary>
        /// <typeparam name="T">the type to convert to</typeparam>
        /// <param name="value">specified text</param>
        /// <returns>An Object that represents the converted text.</returns>
        /// <exception cref="ArgumentNullException">type is null</exception>
        public static T ConvertToTypeOrDefault<T>(this string value)
        {
            return value.ConvertToTypeOrDefault(default(T));
        }

        /// <summary>
        /// Converts the specified text to an object
        /// </summary>
        /// <typeparam name="T">the type to convert to</typeparam>
        /// <param name="value">specified text</param>
        /// <param name="defaultValue">default value if conversion fails</param>
        /// <returns>
        /// An Object that represents the converted text.
        /// </returns>
        /// <exception cref="ArgumentNullException">type is null</exception>
        public static T ConvertToTypeOrDefault<T>(this string value, T defaultValue)
        {
            T retVal = defaultValue;
            if (!String.IsNullOrEmpty(value))
            {
                try
                {
                    TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(T));
                    if (typeConverter.CanConvertFrom(typeof(String)))
                    {
                        retVal =  (T) typeConverter.ConvertFromString(value);
                    }
                    else
                    {
                        throw new NotSupportedException("Can't convert from string");
                    }
                }
                catch (Exception)
                {
                }
            }
            return retVal;
        }
    }
}